package org.jetnuke.common;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.Vector;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;

import net.n3.nanoxml.IXMLElement;
import net.n3.nanoxml.IXMLParser;
import net.n3.nanoxml.IXMLReader;
import net.n3.nanoxml.StdXMLReader;
import net.n3.nanoxml.XMLParserFactory;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.log4j.Logger;
import org.apache.velocity.VelocityContext;
import org.jetnuke.util.JetUtil;

public class ModuleRunner {
	private final static Logger s_log = Logger.getLogger(ModuleRunner.class);
	//private static ModuleRunner _instance = new ModuleRunner();
	private static Set validationSet=Collections.synchronizedSet(new HashSet());
	private static Map validationTable=Collections.synchronizedMap(new HashMap());
	public static ActionForward exec(HttpServletRequest request,
			HttpServletResponse response, DataSource ds, VelocityContext vc,
			IModuleInfo info, String op, IUserInfo ui, IAdminInfo ai)
			throws Exception {
		String actionClassName = null;
		if (op != null) {
			//String template;
			actionClassName = info.getAction(op);
		} else {
			actionClassName = info.getDefaultAction();
		}
		if (actionClassName != null) {

			String role = info.getActionRole(op);
			if (role != null && role.equalsIgnoreCase("user") && ui == null) {
				JetUtil.redirect(vc,response,request.getContextPath()+"/do/your_account");
				return null;
			}
			IAction action = (IAction) Class.forName(actionClassName)
					.newInstance();
			BeanUtils.populate(action, request.getParameterMap());

			return action.exec(request, response, vc, info, op, ui, ai);

		} else {
			String forwardTemplate = info.getForwardTemplate(op);
			String role = info.getForwardRole(op);
			if (role != null && role.equalsIgnoreCase("user") && ui == null) {
				JetUtil.redirect(vc,response,request.getContextPath()+"/do/your_account");
				return null;
			}

			/*
			 * response.setHeader("Cache-Control","no-cache");
			 * response.setHeader("Pragma","no-cache"); response.setDateHeader
			 * ("Expires", -1); response.setHeader("Expires", "Sat, 6 May 1995
			 * 12:00:00 GMT"); response.setContentType("text/html");
			 */

			return new ActionForward(info, forwardTemplate);
		}

	}

	public static ValidationSet loadValidationDoc(ServletContext context, String op, IModuleInfo info) {
		ValidationSet vs = new ValidationSet();

		String str = info.getPath() + op + "-validation.xml";
		String url =null;
		if(validationSet.contains(str)){
			url=(String)validationTable.get(str);
		}else{
			 validationSet.add(str);
			 url = context.getRealPath("")+"/WEB-INF"+str;
			 if(!new File(url).exists())
				 return null;
			 validationTable.put(str,url);
		}
		if (url == null)
			return null;
		//Document doc = null;
		//System.out.println("loading xml validation");
		try {
			BufferedReader br=new BufferedReader(new FileReader(url));
			String line=null;
			StringBuffer buf=new StringBuffer();
			while((line=br.readLine())!=null){
				buf.append(line);
			}
			br.close();
			IXMLParser parser = XMLParserFactory.createDefaultXMLParser();
			IXMLReader reader=StdXMLReader.stringReader(buf.toString());
			parser.setReader(reader);
			IXMLElement xml = (IXMLElement) parser.parse();
			Vector v=xml.getChildrenNamed("param");
			for(int i=0;i<v.size();i++){
				IXMLElement el=(IXMLElement)v.get(i);
				String paramName=el.getAttribute("name",null);
				ValidationItem vi=new ValidationItem();
				vi.setParamName(paramName);
				String requiredValue=el.getAttribute("required",null);
				vi.setRequired(requiredValue != null
						&& requiredValue.equalsIgnoreCase("yes"));
				String minLength=el.getAttribute("minlength",null);
				if(minLength!=null){
					try {
						int k = Integer.parseInt(minLength);
						vi.setMinLength(new Integer(k));
					} catch (Exception e) {

					}
				}
				String maxLength=el.getAttribute("maxlength",null);
				if(maxLength!=null){
					try {
						int k = Integer.parseInt(maxLength);
						vi.setMaxLength(new Integer(k));
					} catch (Exception e) {

					}
				}
				String validationClass=el.getAttribute("class",null);
				if(validationClass!=null){
					vi.setValidationClass(validationClass);
				}
				String label=el.getAttribute("label",null);
				if(label!=null){
					vi.setLabel(label);
				}
				vs.addValidationItem(vi);
			}
			/*DOMParser parser = new DOMParser();
			parser.parse(new InputSource(url.openStream()));
			doc = parser.getDocument();

			NodeList nlist = doc.getElementsByTagName("param");
			for (int i = 0; i < nlist.getLength(); i++) {
				Node node = nlist.item(i);
				String paramName = node.getAttributes().getNamedItem("name")
						.getNodeValue();
				ValidationItem vi = new ValidationItem();
				vi.setParamName(paramName);

				Node nd = node.getAttributes().getNamedItem("required");

				if (nd != null) {
					String requiredValue = nd.getNodeValue();
					vi.setRequired(requiredValue != null
							&& requiredValue.equalsIgnoreCase("yes"));
				}
				nd = node.getAttributes().getNamedItem("minlength");
				if (nd != null) {
					String minLength = nd.getNodeValue();
					try {
						int k = Integer.parseInt(minLength);
						vi.setMinLength(new Integer(k));
					} catch (Exception e) {

					}
				}
				nd = node.getAttributes().getNamedItem("maxlength");
				if (nd != null) {
					String maxLength = nd.getNodeValue();
					try {
						int k = Integer.parseInt(maxLength);
						vi.setMaxLength(new Integer(k));
					} catch (Exception e) {

					}
				}
				nd = node.getAttributes().getNamedItem("class");
				if (nd != null) {
					String validationClass = nd.getNodeValue();
					vi.setValidationClass(validationClass);
				}
				nd = node.getAttributes().getNamedItem("label");
				if (nd != null) {
					String label = nd.getNodeValue();
					vi.setLabel(label);
				}

				//System.out.println(requiredValue);
				vs.addValidationItem(vi);
			}*/

		} catch (Exception e) {
			s_log.error(e);
		}
		return vs;

	}

}
